home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / Mail / Queue / Container / mdb.php < prev   
PHP Script  |  2004-03-24  |  19KB  |  501 lines

  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PEAR :: Mail :: Queue :: MDB Container                                       |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 1997-2003 The PHP Group                                |
  6. // +----------------------------------------------------------------------+
  7. // | This source file is subject to version 2.0 of the PHP license,       |
  8. // | that is bundled with this package in the file LICENSE, and is        |
  9. // | available at through the world-wide-web at                           |
  10. // | http://www.php.net/license/2_02.txt.                                 |
  11. // | If you did not receive a copy of the PHP license and are unable to   |
  12. // | obtain it through the world-wide-web, please send a note to          |
  13. // | license@php.net so we can mail you a copy immediately.               |
  14. // +----------------------------------------------------------------------+
  15. // | Note: This is a MDB-oriented rewrite of Queue/Container/db.php       |
  16. // +----------------------------------------------------------------------+
  17. // | Author: Lorenzo Alberton <l.alberton at quipo.it>                    |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: mdb.php,v 1.9 2004/02/29 09:19:14 quipo Exp $
  21.  
  22. /**
  23.  * Storage driver for fetching mail queue data from a PEAR::MDB database
  24.  *
  25.  * This storage driver can use all databases which are supported
  26.  * by the PEAR MDB abstraction layer.
  27.  *
  28.  * @author   Lorenzo Alberton <l.alberton at quipo.it>
  29.  * @version  $Id: mdb.php,v 1.9 2004/02/29 09:19:14 quipo Exp $
  30.  * @package  Mail_Queue
  31.  */
  32. require_once 'MDB.php';
  33. require_once 'Mail/Queue/Container.php';
  34.  
  35. /**
  36. * PEAR/MDB Mail_Queue Container.
  37. *
  38. * NB: The field 'changed' has no meaning for the Cache itself. It's just there
  39. * because it's a good idea to have an automatically updated timestamp
  40. * field for debugging in all of your tables.
  41. *
  42. * A XML MDB-compliant schema example for the table needed is provided.
  43. * Look at the file "mdb_mail_queue_schema.xml" for that.
  44. *
  45. * -------------------------------------------------------------------------
  46. * A basic usage example:
  47. * -------------------------------------------------------------------------
  48. *
  49. * $container_options = array(
  50. *   'type'        => 'mdb',
  51. *   'database'    => 'dbname',
  52. *   'phptype'     => 'mysql',
  53. *   'username'    => 'root',
  54. *   'password'    => '',
  55. *   'mail_table'  => 'mail_queue'
  56. * );
  57. *   //optionally, a 'dns' string can be provided instead of db parameters.
  58. *   //look at MDB::connect() method or at MDB docs for details.
  59. *
  60. * $mail_options = array(
  61. *   'driver'   => 'smtp',
  62. *   'host'     => 'your_smtp_server.com',
  63. *   'port'     => 25,
  64. *   'auth'     => false,
  65. *   'username' => '',
  66. *   'password' => ''
  67. * );
  68. *
  69. * $mail_queue =& new Mail_Queue($container_options, $mail_options);
  70. * *****************************************************************
  71. * // Here the code differentiates wrt you want to add an email to the queue
  72. * // or you want to send the emails that already are in the queue.
  73. * *****************************************************************
  74. * // TO ADD AN EMAIL TO THE QUEUE
  75. * *****************************************************************
  76. * $from             = 'user@server.com';
  77. * $from_name        = 'admin';
  78. * $recipient        = 'recipient@other_server.com';
  79. * $recipient_name   = 'recipient';
  80. * $message          = 'Test message';
  81. * $from_params      = empty($from_name) ? '"'.$from_name.'" <'.$from.'>' : '<'.$from.'>';
  82. * $recipient_params = empty($recipient_name) ? '"'.$recipient_name.'" <'.$recipient.'>' : '<'.$recipient.'>';
  83. * $hdrs = array( 'From'    => $from_params,
  84. *                'To'      => $recipient_params,
  85. *                'Subject' => "test message body"  );
  86. * $mime =& new Mail_mime();
  87. * $mime->setTXTBody($message);
  88. * $body = $mime->get();
  89. * $hdrs = $mime->headers($hdrs);
  90. *
  91. * // Put message to queue
  92. * $mail_queue->put( $from, $recipient, $hdrs, $body );
  93. * //Also you could put this msg in more advanced mode [look at Mail_Queue docs for details]
  94. * $seconds_to_send = 3600;
  95. * $delete_after_send = false;
  96. * $id_user = 7;
  97. * $mail_queue->put( $from, $recipient, $hdrs, $body, $seconds_to_send, $delete_after_send, $id_user );
  98. *
  99. * *****************************************************************
  100. * // TO SEND EMAILS IN THE QUEUE
  101. * *****************************************************************
  102. * // How many mails could we send each time
  103. * $max_ammount_mails = 50;
  104. * $mail_queue =& new Mail_Queue($container_options, $mail_options);
  105. * $mail_queue->sendMailsInQueue($max_ammount_mails);
  106. * *****************************************************************
  107. * // end usage example
  108. * -------------------------------------------------------------------------
  109. *
  110. * //You can also send the emails one by one:
  111. *
  112. * //set the internal buffer size according your
  113. * //memory resources (the number indicates how
  114. * //many emails can stay in the buffer at any
  115. * //given time
  116. * $mail_queue->setBufferSize(20);
  117. *
  118. * //loop through the stored emails and send them
  119. * while ($mail = $mail_queue->get()) {
  120. *     $result = $mail_queue->sendMail($mail);
  121. * }
  122. */
  123.  
  124. /**
  125.  * Mail_Queue_Container_mdb
  126.  */
  127. class Mail_Queue_Container_mdb extends Mail_Queue_Container
  128. {
  129.     // {{{ class vars
  130.  
  131.     /**
  132.      * Reference to the current database connection.
  133.      * @var object PEAR::MDB instance
  134.      */
  135.     var $db;
  136.  
  137.     /**
  138.      * Table for sql database
  139.      * @var  string
  140.      */
  141.     var $mail_table = 'mail_queue';
  142.  
  143.     /**
  144.      * @var string  the name of the sequence for this table
  145.      */
  146.     var $sequence = null;
  147.  
  148.     // }}}
  149.     // {{{ Mail_Queue_Container_mdb()
  150.  
  151.     /**
  152.      * Contructor
  153.      *
  154.      * Mail_Queue_Container_mdb:: Mail_Queue_Container_mdb()
  155.      *
  156.      * @param mixed $options    An associative array of option names and
  157.      *                          their values. See MDB_common::setOption
  158.      *                          for more information about connection options.
  159.      *
  160.      * @access public
  161.      */
  162.     function Mail_Queue_Container_mdb($options)
  163.     {
  164.         if (!is_array($options)) {
  165.             return new Mail_Queue_Error(MAILQUEUE_ERROR_NO_OPTIONS,
  166.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  167.                 'No options specified!');
  168.         }
  169.         if (isset($options['mail_table'])) {
  170.             $this->mail_table = $options['mail_table'];
  171.             unset($options['mail_table']);
  172.         }
  173.         if (isset($options['sequence'])) {
  174.             $this->sequence = $options['sequence'];
  175.             unset($options['sequence']);
  176.         } else {
  177.             $this->sequence = $this->mail_table;
  178.         }
  179.         if (!empty($options['pearErrorMode'])) {
  180.             $this->pearErrorMode = $options['pearErrorMode'];
  181.         }
  182.         if (isset($options['dsn'])) {
  183.             $dsn = $options['dsn'];
  184.         } else {
  185.             $dsn = $options;
  186.         }
  187.         $this->db = &MDB::Connect($dsn);
  188.         if (MDB::isError($this->db)) {
  189.             return new Mail_Queue_Error(MAILQUEUE_ERROR_CANNOT_CONNECT,
  190.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  191.                 'MDB::connect failed: '. $this->db->getMessage());
  192.         } else {
  193.             $this->db->setFetchMode(MDB_FETCHMODE_ASSOC);
  194.         }
  195.         $this->setOption();
  196.     }
  197.  
  198.     // }}}
  199.     // {{{ _preload()
  200.  
  201.     /**
  202.      * Preload mail to queue.
  203.      *
  204.      * @return mixed   True on success else Mail_Queue_Error object.
  205.      * @access private
  206.      */
  207.     function _preload()
  208.     {
  209.         $query = 'SELECT id FROM ' . $this->mail_table
  210.                 .' WHERE sent_time IS NULL AND try_sent < '. $this->try
  211.                 .' AND time_to_send < '.$this->db->getTimestampValue(date("Y-m-d H:i:s"))
  212.                 .' ORDER BY time_to_send';
  213.         if ($this->limit != MAILQUEUE_ALL) {
  214.             $res = $this->db->limitQuery($query, null, $this->offset, $this->limit);
  215.         } else {
  216.             $res = $this->db->query($query);
  217.         }
  218.  
  219.         if (MDB::isError($res)) {
  220.             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  221.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  222.                 'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  223.         }
  224.  
  225.         $this->_last_item = 0;
  226.         $this->queue_data = array(); //reset buffer
  227.         while ($row = $this->db->fetchInto($res, MDB_FETCHMODE_ASSOC)) {
  228.             $this->queue_data[$this->_last_item] = $this->getMailById($row['id']);
  229.             if (Mail_Queue::isError($this->queue_data[$this->_last_item])) {
  230.                 return $this->queue_data[$this->_last_item];
  231.             }
  232.             $this->_last_item++;
  233.         }
  234.         @$this->db->freeResult($res);
  235.         return true;
  236.     }
  237.  
  238.     // }}}
  239.     // {{{ put()
  240.  
  241.     /**
  242.      * Put new mail in queue and save in database.
  243.      *
  244.      * Mail_Queue_Container::put()
  245.      *
  246.      * @param string  $time_to_send  When mail have to be send
  247.      * @param integer $id_user  Sender id
  248.      * @param string  $ip  Sender ip
  249.      * @param string  $from  Sender e-mail
  250.      * @param string  $to  Recipient e-mail
  251.      * @param string  $hdrs  Mail headers (in RFC)
  252.      * @param string  $body  Mail body (in RFC)
  253.      * @param bool    $delete_after_send  Delete or not mail from db after send
  254.      * @return mixed  ID of the record where this mail has been put
  255.      *                or Mail_Queue_Error on error
  256.      * @access public
  257.      **/
  258.     function put($time_to_send, $id_user, $ip, $sender,
  259.                 $recipient, $headers, $body, $delete_after_send=true)
  260.     {
  261.         $id = $this->db->nextId($this->sequence);
  262.         if (empty($id)) {
  263.             return new Mail_Queue_Error(MAILQUEUE_ERROR,
  264.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  265.                 'Cannot create id in: '.$this->sequence);
  266.         }
  267.         $query = 'INSERT INTO '. $this->mail_table
  268.                 .' (id, create_time, time_to_send, id_user, ip'
  269.                 .', sender, recipient, delete_after_send) VALUES ('
  270.                 .       $this->db->getIntegerValue($id)
  271.                 .', ' . $this->db->getTimestampValue(date("Y-m-d H:i:s"))
  272.                 .', ' . $this->db->getTimestampValue($time_to_send)
  273.                 .', ' . $this->db->getIntegerValue($id_user)
  274.                 .', ' . $this->db->getTextValue($ip)
  275.                 .', ' . $this->db->getTextValue($sender)
  276.                 .', ' . $this->db->getTextValue($recipient)
  277.                 .', ' . ($delete_after_send ? 1 : 0)
  278.                 .')';
  279.         $res = $this->db->query($query);
  280.         if (MDB::isError($res)) {
  281.             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  282.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  283.                 'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  284.         }
  285.         foreach (array('headers', 'body') as $field) {
  286.             $query = 'UPDATE ' . $this->mail_table .' SET ' .$field. '=?'
  287.                     .' WHERE id=' . $this->db->getIntegerValue($id);
  288.             if ($prepared_query = $this->db->prepareQuery($query)) {
  289.                 $char_lob = array('Error' => '',
  290.                                   'Type'  => 'data',
  291.                                   'Data'  => $$field);
  292.                 if (MDB::isError($clob = $this->db->createLob($char_lob))) {
  293.                     return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  294.                         $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  295.                         'MDB: query failed - "'.$query.'" - '.$clob->getMessage());
  296.                 }
  297.                 $this->db->setParamClob($prepared_query,1,$clob,$field);
  298.                 if (MDB::isError($error = $this->db->executeQuery($prepared_query))) {
  299.                     return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  300.                         $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  301.                         'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  302.                 }
  303.                 $this->db->destroyLob($clob);
  304.                 $this->db->freePreparedQuery($prepared_query);
  305.             } else {
  306.                 //prepared query failed
  307.                 return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  308.                         $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  309.                         'MDB: query failed - "'.$query.'" - '.$clob->getMessage());
  310.             }
  311.  
  312.         }
  313. /*
  314.         $this->_last_item++;
  315.         $this->queue_data[$this->_last_item] = new Mail_Queue_Body(
  316.             $id,
  317.             date('d-m-y G:i:s'),
  318.             $time_to_send,
  319.             null,
  320.             $id_user,
  321.             $ip,
  322.             $sender,
  323.             $recipient,
  324.             unserialize($headers),
  325.             unserialize($body),
  326.             $delete_after_send,
  327.             0
  328.         );
  329. */
  330.         return $id;
  331.     }
  332.  
  333.     // }}}
  334.     // {{{ countSend()
  335.  
  336.     /**
  337.      * Check how many times mail was sent.
  338.      *
  339.      * @param object  Mail_Queue_Body
  340.      * @return mixed  Integer or Mail_Queue_Error class if error.
  341.      * @access public
  342.      */
  343.     function countSend($mail)
  344.     {
  345.         if (!is_object($mail) || !is_a($mail, 'mail_queue_body')) {
  346.             return new Mail_Queue_Error(MAILQUEUE_ERROR_UNEXPECTED,
  347.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  348.                 'Expected: Mail_Queue_Body class');
  349.         }
  350.         $count = $mail->try();
  351.         $query = 'UPDATE ' . $this->mail_table
  352.                 .' SET try_sent = ' . $this->db->getIntegerValue($count)
  353.                 .' WHERE id = '     . $this->db->getIntegerValue($mail->getId());
  354.         $res = $this->db->query($query);
  355.  
  356.         if (MDB::isError($res)) {
  357.             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  358.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  359.                 'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  360.         }
  361.         return $count;
  362.     }
  363.  
  364.     // }}}
  365.     // {{{ setAsSent()
  366.  
  367.     /**
  368.      * Set mail as already sent.
  369.      *
  370.      * @param object Mail_Queue_Body object
  371.      * @return bool
  372.      * @access public
  373.      */
  374.     function setAsSent($mail)
  375.     {
  376.         if (!is_object($mail) || !is_a($mail, 'mail_queue_body')) {
  377.             return new Mail_Queue_Error(MAILQUEUE_ERROR_UNEXPECTED,
  378.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  379.                 'Expected: Mail_Queue_Body class');
  380.         }
  381.         $query = 'UPDATE ' . $this->mail_table
  382.                 .' SET sent_time = '.$this->db->getTimestampValue(date("Y-m-d H:i:s"))
  383.                 .' WHERE id = '. $this->db->getIntegerValue($mail->getId());
  384.  
  385.         $res = $this->db->query($query);
  386.  
  387.         if (MDB::isError($res)) {
  388.             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  389.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  390.                 'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  391.         }
  392.  
  393.         return true;
  394.     }
  395.  
  396.     // }}}
  397.     // {{{ getMailById()
  398.  
  399.     /**
  400.      * Return mail by id $id (bypass mail_queue)
  401.      *
  402.      * @param integer $id  Mail ID
  403.      * @return mixed  Mail object or false on error.
  404.      * @access public
  405.      */
  406.     function getMailById($id)
  407.     {
  408.         $query = 'SELECT id, create_time, time_to_send, sent_time'
  409.                 .', id_user, ip, sender, recipient, delete_after_send'
  410.                 .', try_sent FROM ' . $this->mail_table
  411.                 .' WHERE id = '     . $this->db->getTextValue($id);
  412.         $res = $this->db->query($query);
  413.         if (MDB::isError($res)) {
  414.             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  415.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  416.                 'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  417.         }
  418.         $row = $this->db->fetchRow($res, MDB_FETCHMODE_ASSOC);
  419.         if (!is_array($row)) {
  420.             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  421.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  422.                 'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  423.         }
  424.         //now fetch lobs...
  425.         foreach (array('headers','body') as $field) {
  426.             $query = 'SELECT '.$field.' FROM ' . $this->mail_table
  427.                     .' WHERE id=' . $this->db->getIntegerValue($id);
  428.             $res = $this->db->query($query);
  429.             if (MDB::isError($res)) {
  430.                 //return new Mail_Queue_Error('MDB::query failed: '
  431.                 //          . $result->getMessage(), __FILE__, __LINE__);
  432.                 $row[$field] = ''; //Not sure if this is better than raising the error...
  433.             } else {
  434.                 if ($this->db->endOfResult($res)) {
  435.                     //no rows returned
  436.                     $row[$field] = '';
  437.                 } else {
  438.                     $clob = $this->db->fetchClob($res,0,$field);
  439.                     if (MDB::isError($clob)) {
  440.                         return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  441.                             $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  442.                             'MDB: query failed - "'.$query.'" - '.$clob->getMessage());
  443.                     }
  444.  
  445.                     $row[$field] = '';
  446.                     while (!$this->db->endOfLOB($clob)) {
  447.                         if (MDB::isError($error =
  448.                                         $this->db->readLob($clob, $data, 8192) < 0)) {
  449.                             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  450.                                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  451.                                 'MDB: query failed - "'.$query.'" - '.$error->getMessage());
  452.                         }
  453.                         $row[$field] .= $data;
  454.                         unset($data);
  455.                     }
  456.                     $this->db->destroyLob($clob);
  457.                 }
  458.             }
  459.         }
  460.  
  461.         return new Mail_Queue_Body(
  462.             $row['id'],
  463.             $row['create_time'],
  464.             $row['time_to_send'],
  465.             $row['sent_time'],
  466.             $row['id_user'],
  467.             $row['ip'],
  468.             $row['sender'],
  469.             $row['recipient'],
  470.             unserialize($row['headers']),
  471.             unserialize($row['body']),
  472.             $row['delete_after_send'],
  473.             $row['try_sent']
  474.         );
  475.     }
  476.  
  477.     // }}}
  478.     // {{{ deleteMail()
  479.  
  480.     /**
  481.      * Remove from queue mail with $id identifier.
  482.      *
  483.      * @param integer $id  Mail ID
  484.      * @return bool  True on success else Mail_Queue_Error class
  485.      * @access public
  486.      */
  487.     function deleteMail($id) {
  488.         $query = 'DELETE FROM ' . $this->mail_table
  489.                 .' WHERE id = ' . $this->db->getTextValue($id);
  490.         $res = $this->db->query($query);
  491.         if (MDB::isError($res)) {
  492.             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  493.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  494.                 'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  495.         }
  496.         return true;
  497.     }
  498.  
  499.     // }}}
  500. }
  501. ?>